package com.explment.lens.controller.login;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.explment.lens.entity.SysUserEntity;
import com.explment.lens.entity.securityuser.LoginUser;
import com.explment.lens.service.SysUserService;
import com.explment.lens.service.redis.RedisService;
import com.explment.lens.service.token.TokenRefreshService;
import com.explment.lens.utils.jwt.JwtTokenProvider;
import com.explment.lens.utils.result.ResultCode;
import com.explment.lens.utils.result.ResultData;
import io.micrometer.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api")
public class LoginController {

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private TokenRefreshService tokenRefreshService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 用户登录接口
     * 用户通过该接口进行登录操作，验证用户名和密码的正确性，并生成对应的Token返回给客户端。
     *
     * @param loginUser 登录用户信息，包含用户名和密码
     * @return 返回登录结果，包含accessToken和refreshToken的Map，或者返回错误信息
     */
    @PostMapping("/login")
    public ResultData login(@RequestBody LoginUser loginUser) {

        Map map = new HashMap();
        if (null != loginUser) {
            String username = loginUser.getUsername();
            if (StringUtils.isBlank(username)) {
                return ResultData.fail(ResultCode.BAD_REQUEST, "用户名不能为空");
            }
            SysUserEntity sysUser = sysUserService.getOne(new QueryWrapper<SysUserEntity>().eq("account", username));
            if (null == sysUser) {
                return ResultData.fail(ResultCode.BAD_REQUEST, "用户不存在");
            }
            if (!passwordEncoder.matches(loginUser.getPassword(), sysUser.getPassword())) {
                return ResultData.fail(ResultCode.BAD_REQUEST, "密码错误");
            }

            // 生成Token
            String accessToken = jwtTokenProvider.generateAccessToken(username);
            String refreshToken = jwtTokenProvider.generateRefreshToken(username);
            Authentication auth = new UsernamePasswordAuthenticationToken(
                    username,
                    sysUser.getPassword(),
                    Collections.emptyList()
            );
            SecurityContextHolder.getContext().setAuthentication(auth);
            // 存储Access Token 用于请求携带,不同的存储时间
            redisService.set("access:" + username, refreshToken, jwtTokenProvider.getAccessExpiration());
            // 存储Refresh Token，一周内 用于刷新Token,不同的存储时间
            redisService.set("refresh:" + username, refreshToken, jwtTokenProvider.getRefreshExpiration());

            map.put("accessToken", accessToken);
            map.put("refreshToken", refreshToken);
            return ResultData.success(map);
        } else {
            return ResultData.fail(ResultCode.BAD_REQUEST, "登录失败");
        }
    }

    /**
     * 刷新Token
     *
     * @param refreshToken
     * @return
     */
    @PostMapping("/refresh")
    public ResultData refresh(@RequestParam String refreshToken) {
        return ResultData.success(tokenRefreshService.refreshTokens(refreshToken));
    }

    /**
     * 注册用户
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/register")
    public ResultData register(@RequestBody SysUserEntity sysUser) {
        return ResultData.success(sysUserService.save(sysUser));
    }

    @PostMapping("/logout")
    public ResultData logout(@RequestParam String refreshToken) {
        return tokenRefreshService.logout(refreshToken);
    }
}
